package com.ybear.ybnetworkutil.http;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.ybear.ybnetworkutil.request.Request;

import java.io.File;
import java.util.Map;

import okhttp3.Headers;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okio.ByteString;

public class Body {
    private final ClientBuilder mClientBuilder;
    private final Request mRequest;
    private final BodyType mBodyType;
    private final MediaType mMediaType;

    public Body(@NonNull ClientBuilder builder, @NonNull Request request, @NonNull BodyType bodyType) {
        mClientBuilder = builder;
        mRequest = request;
        mBodyType = bodyType;
        mMediaType = MediaType.create();
    }

    /* mediaType */

    public Body mediaTypeForm() {
        mMediaType.form();
        return this;
    }

    public Body mediaTypeJson() {
        mMediaType.json();
        return this;
    }

    public Body mediaTypeJs() {
        mMediaType.js();
        return this;
    }

    public Body mediaTypeXml() {
        mMediaType.xml();
        return this;
    }

    public Body mediaTypeTextPlain() {
        mMediaType.textPlain();
        return this;
    }

    public Body mediaTypeTextXml() {
        mMediaType.textXml();
        return this;
    }

    public Body mediaTypeTextHtml() {
        mMediaType.textHtml();
        return this;
    }

    public String toMediaType() { return mMediaType.toMediaType(); }

    okhttp3.MediaType toOkMediaType() { return mMediaType.toOkMediaType(); }

    /* request */

    public ClientBuilder requestBody() {
        mBodyType.requestBody( mMediaType, mRequest.toParamBodyString() );
        return mClientBuilder;
    }

    public ClientBuilder requestBody(File file) {
        mBodyType.requestBody( mMediaType, file );
        return mClientBuilder;
    }

    public ClientBuilder requestBody(byte[] bytes) {
        mBodyType.requestBody( mMediaType, bytes );
        return mClientBuilder;
    }

    public ClientBuilder requestBody(byte[] content, int offset, int byteCount) {
        mBodyType.requestBody( mMediaType, content, offset, byteCount );
        return mClientBuilder;
    }

    public ClientBuilder requestBody(ByteString content) {
        mBodyType.requestBody( mMediaType, content );
        return mClientBuilder;
    }

    public ClientBuilder formBody() {
        mBodyType.formBody( mRequest.getParam().getMap() );
        return mClientBuilder;
    }

    public ClientBuilder formBodyOfEncoded() {
        mBodyType.formBodyOfEncoded( mRequest.getParam().getMap() );
        return mClientBuilder;
    }

    public ClientBuilder formBody(Map<String, Object> content, Map<String, Object> encoded) {
        mBodyType.formBody( content, encoded );
        return mClientBuilder;
    }

    public ClientBuilder multipartBody(okhttp3.MediaType type) {
        mBodyType.multipartBody( type );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfDataPart(okhttp3.MediaType type) {
        mBodyType.multipartBodyOfDataPart( type, mRequest.getParam().getMap() );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfDataPart(okhttp3.MediaType type,
                                                 String name,
                                                 @Nullable String filename,
                                                 RequestBody body) {
        mBodyType.multipartBodyOfDataPart( type, name, filename, body );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfPart(okhttp3.MediaType type, MultipartBody.Part part) {
        mBodyType.multipartBodyOfPart( type, part );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfPart(okhttp3.MediaType type, RequestBody body) {
        mBodyType.multipartBodyOfPart( type, body );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfPart(okhttp3.MediaType type,
                                             @Nullable Headers headers,
                                             RequestBody body) {
        mBodyType.multipartBodyOfPart( type, headers, body );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfFileAndParam(String mediaType, String name, File file) {
        mBodyType.multipartBodyOfFile( mediaType, mRequest.getParam().getMap(), name, file );
        return mClientBuilder;
    }

    public ClientBuilder multipartBodyOfFile(String mediaType, String name, File file) {
        mBodyType.multipartBodyOfFile( mediaType, name, file );
        return mClientBuilder;
    }
}
